﻿#region zh-CHS 2006 - 2007 DemoSoft 团队 | en 2006 - 2007 DemoSoft Team

//     NOTES
// ---------------
//
// This file is a part of the G.O.S.E(Game Online Server Engine) for .NET.
//
//                 2006-2007 DemoSoft Team
//
//
// First Version : by H.Q.Cai - mailto:caihuanqing@hotmail.com

/***************************************************************************
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU Lesser General Public License as published
 *   by the Free Software Foundation; either version 2.1 of the License, or
 *   (at your option) any later version.
 *
 ***************************************************************************/

#region zh-CHS 包含名字空间 | en Include namespace
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using Demo_G.O.S.E.ServerEngine.Common;
#endregion

namespace Demo_G.O.S.E.ServerEngine.Network.DLL
{
    /// <summary>
    /// 客户段的主处理
    /// </summary>
    [MultiThreadedSupportgAttribute( "当前的类所有成员都可锁定,支持多线程操作" )]
    public class ACESocketClient
    {
        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 客户段的主处理指针
        /// </summary>
        private IntPtr m_SocketMainServer                                                                       = IntPtr.Zero;
        /// <summary>
        /// 客户段的主处理管理句柄
        /// </summary>
        private ACESocketHandlerManagerAtClient m_SocketHandlerManagerAtClient                                  = new ACESocketHandlerManagerAtClient();

        /// <summary>
        /// 处理数据的回调函数
        /// </summary>
        private DelegateProcessMessageBlock m_ProcessMessageBlock                                               = null;
        /// <summary>
        /// 处理断开的回调函数
        /// </summary>
        private DelegateDisconnect m_Disconnect                                                                 = null;
        #endregion

        #region zh-CHS 构造和初始化和清理 | en Constructors and Initializers and Dispose
        /// <summary>
        /// 初始化构造
        /// </summary>
        public ACESocketClient()
        {
            m_ProcessMessageBlock   = new DelegateProcessMessageBlock(this.OnProcessMessageBlock);
            m_Disconnect            = new DelegateDisconnect(this.OnDisconnect);
        }
        #endregion

        #region zh-CHS 共有属性 | en Public Properties
        /// <summary>
        /// 客户端是够已经连接
        /// </summary>
        public bool IsConnected
        {
            get { return ACESocketClient.ACESocketClient_IsConnected( m_SocketMainServer ); }
        }

        /// <summary>
        /// 客户端的管理句柄
        /// </summary>
        public ACESocketHandlerManagerAtClient SocketHandlerManager
        {
            get { return m_SocketHandlerManagerAtClient; }
        }
        #endregion

        #region zh-CHS 共有方法 | en Public Methods
        /// <summary>
        /// 开始连接服务端
        /// </summary>
        /// <param name="strHostNamePort"></param>
        public bool StartConnectServer( string strHostNamePort )
        {
            if ( ACESocketClient.ACESocketClient_StartConnectServer( strHostNamePort, m_ProcessMessageBlock, m_Disconnect, ref m_SocketMainServer ) == false )
            {
                Debug.WriteLine( "ACESocketClient.StartConnectServer(...) - ACESocketClient.ACESocketClient_StartConnectServer(...) == false error!" );
                return false;
            }

            IntPtr l_SocketHandlerManagerAtClient = IntPtr.Zero;
            if ( ACESocketClient.ACESocketClient_GetSocketHandlerManager( ref l_SocketHandlerManagerAtClient, m_SocketMainServer ) == false )
            {
                Debug.WriteLine( "ACESocketClient.StartConnectServer(...) - ACESocketClient.ACESocketClient_GetSocketHandlerManager(...) == false error!" );
                return false;
            }

            if ( l_SocketHandlerManagerAtClient == IntPtr.Zero )
            {
                Debug.WriteLine( "ACESocketClient.StartConnectServer(...) - l_SocketHandlerManagerAtClient == IntPtr.Zero error!" );
                return false;
            }

            m_SocketHandlerManagerAtClient.Value = l_SocketHandlerManagerAtClient;
            return true;
        }

        /// <summary>
        /// 发送数据到服务端
        /// </summary>
        /// <param name="byteBuffer"></param>
        /// <param name="iLength"></param>
        public void SendBuffer( byte[] byteBuffer, int iLength )
        {
            if ( m_SocketMainServer == IntPtr.Zero )
            {
                Debug.WriteLine( "ACESocketClient.SendBuffer(...) - m_SocketMainServer == IntPtr.Zero error!" );
                return;
            }

            if ( this.IsConnected == false )
            {
                Debug.WriteLine( "ACESocketClient.SendBuffer(...) - this.IsConnected == false error!" );
                return;
            }

            ACEClientHandlerAtClient l_ClientHandlerAtClient    = m_SocketHandlerManagerAtClient.GetClientHandler();
            if ( l_ClientHandlerAtClient == null )
            {
                Debug.WriteLine( "ACESocketClient.SendBuffer(...) - l_ClientHandlerAtClient == null error!" );
                return;
            }

            ACEMessageBlock l_MessageBlock  = m_SocketHandlerManagerAtClient.GetNewSendMessageBlock();
            if ( l_MessageBlock == null )
            {
                Debug.WriteLine( "ACESocketClient.SendBuffer(...) - l_MessageBlock == null error!" );
                return;
            }

            Marshal.Copy( byteBuffer, 0, l_MessageBlock.WriteIntPtr(), iLength );
            l_MessageBlock.WriteIntPtrLength( iLength );

            l_ClientHandlerAtClient.SendTo( l_MessageBlock );
        }

        /// <summary>
        /// 停止连接
        /// </summary>
        public void StopConnect()
        {
            ACESocketClient.ACESocketClient_StopConnect( m_SocketMainServer );
        }
        #endregion

        #region zh-CHS 共有事件 | en Public Event
        /// <summary>
        /// 处理数据的事件
        /// </summary>
        public event EventDelegateProcessMessageBlockClient EventThreadProcessMessageBlock;
        /// <summary>
        /// 处理断开的事件
        /// </summary>
        public event EventDelegateDisconnectClient EventThreadDisconnect;
        #endregion

        #region zh-CHS 私有委托 | en Private Delegate
        /// <summary>
        /// 处理数据的委托
        /// </summary>
        /// <param name="pRecvMessageBlock"></param>
        /// <param name="pNonceClientHandler"></param>
        /// <param name="pHandlerManager"></param>
        private delegate void DelegateProcessMessageBlock(IntPtr pRecvMessageBlock, IntPtr pNonceClientHandler, IntPtr pHandlerManager);
        /// <summary>
        /// 处理断开的委托
        /// </summary>
        /// <param name="pNonceClientHandler"></param>
        /// <param name="pHandlerManager"></param>
        private delegate void DelegateDisconnect(IntPtr pNonceClientHandler, IntPtr pHandlerManager);
        #endregion

        #region zh-CHS 私有的事件处理函数 | en Private Event Handlers
        #region zh-CHS 私有成员变量 | en Private Member Variables
        // 为优化而采用内存池
        /// <summary>
        /// 数据区
        /// </summary>
        private ACEProcessMessageBlockPool<ACEMessageBlock> m_MessageBlockPool = new ACEProcessMessageBlockPool<ACEMessageBlock>( "ACESocketClient - ACEMessageBlock", 2048 );
        /// <summary>
        /// 主处理
        /// </summary>
        private ACEProcessMessageBlockPool<ACEClientHandlerAtClient> m_ClientHandlerAtClientPool = new ACEProcessMessageBlockPool<ACEClientHandlerAtClient>( "ACESocketClient - ACEClientHandlerAtClient", 2048 );
        /// <summary>
        /// 主处理管理句柄
        /// </summary>
        private ACEProcessMessageBlockPool<ACESocketHandlerManagerAtClient> m_SocketHandlerManagerAtClientPool = new ACEProcessMessageBlockPool<ACESocketHandlerManagerAtClient>( "ACESocketClient - ACESocketHandlerManagerAtClient", 2048 );
        #endregion
        /// <summary>
        /// 处理数据
        /// </summary>
        /// <param name="pRecvMessageBlock"></param>
        /// <param name="pNonceClientHandler"></param>
        /// <param name="pAllHandlerManager"></param>
        private void OnProcessMessageBlock(IntPtr pRecvMessageBlock, IntPtr pNonceClientHandler, IntPtr pAllHandlerManager)
        {
            if (EventThreadProcessMessageBlock != null)
            {
                // 从内存池获取内存 - 调用太频繁内存池优化
                ACEMessageBlock l_RecvMessageBlock = m_MessageBlockPool.AcquirePoolContent();
                if (l_RecvMessageBlock == null)
                {
                    Debug.WriteLine("ACESocketClient.OnProcessMessageBlock(...) - l_RecvMessageBlock == null error!");
                    
                    return;
                }
                l_RecvMessageBlock.Value = pRecvMessageBlock;

                ACEClientHandlerAtClient l_NonceClientHandler = m_ClientHandlerAtClientPool.AcquirePoolContent();
                if (l_NonceClientHandler == null)
                {
                    Debug.WriteLine("ACESocketClient.OnProcessMessageBlock(...) - l_NonceClientHandler == null error!");
                    
                    m_MessageBlockPool.ReleasePoolContent(l_RecvMessageBlock);

                    return;
                }
                l_NonceClientHandler.Value = pNonceClientHandler;

                ACESocketHandlerManagerAtClient l_AllHandlerManager = m_SocketHandlerManagerAtClientPool.AcquirePoolContent();
                if (l_AllHandlerManager == null)
                {
                    Debug.WriteLine("ACESocketClient.OnProcessMessageBlock(...) - l_AllHandlerManager == null error!");
                    
                    m_MessageBlockPool.ReleasePoolContent(l_RecvMessageBlock);
                    m_ClientHandlerAtClientPool.ReleasePoolContent(l_NonceClientHandler);
                    return;
                }
                l_AllHandlerManager.Value = pAllHandlerManager;

                EventThreadProcessMessageBlock(l_RecvMessageBlock, l_NonceClientHandler, l_AllHandlerManager);

                // 释放入内存池
                m_MessageBlockPool.ReleasePoolContent(l_RecvMessageBlock);
                m_ClientHandlerAtClientPool.ReleasePoolContent(l_NonceClientHandler);
                m_SocketHandlerManagerAtClientPool.ReleasePoolContent(l_AllHandlerManager);
            }
        }

        /// <summary>
        /// 处理断开
        /// </summary>
        /// <param name="pNonceClientHandler"></param>
        /// <param name="pAllHandlerManager"></param>
        private void OnDisconnect(IntPtr pNonceClientHandler, IntPtr pAllHandlerManager)
        {
            if (EventThreadDisconnect != null)
            {
                // 从内存池获取内存 - 调用太频繁内存池优化
                ACEClientHandlerAtClient l_NonceClientHandler = m_ClientHandlerAtClientPool.AcquirePoolContent();
                if (l_NonceClientHandler == null)
                {
                    Debug.WriteLine("ACESocketClient.OnProcessMessageBlock(...) - l_NonceClientHandler == null error!");
                    
                    return;
                }
                l_NonceClientHandler.Value = pNonceClientHandler;

                ACESocketHandlerManagerAtClient l_AllHandlerManager = m_SocketHandlerManagerAtClientPool.AcquirePoolContent();
                if (l_AllHandlerManager == null)
                {
                    Debug.WriteLine("ACESocketClient.OnProcessMessageBlock(...) - l_AllHandlerManager == null error!");
                    
                    m_ClientHandlerAtClientPool.ReleasePoolContent(l_NonceClientHandler);
                    return;
                }
                l_AllHandlerManager.Value = pAllHandlerManager;

                EventThreadDisconnect(l_NonceClientHandler, l_AllHandlerManager);

                // 释放入内存池
                m_ClientHandlerAtClientPool.ReleasePoolContent(l_NonceClientHandler);
                m_SocketHandlerManagerAtClientPool.ReleasePoolContent(l_AllHandlerManager);
            }
        }
        #endregion

        #region zh-CHS 引入DLL接口 | en DLL Import
        /// <summary>
        /// dll 调用
        /// </summary>
        /// <param name="strHostNamePort"></param>
        /// <param name="DelegateProcessMessageBlock"></param>
        /// <param name="DelegateDisconnect"></param>
        /// <param name="pSocketMainServer"></param>
        /// <returns></returns>
        [DllImport( "Demo G.O.S.E.Net.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode )]
        private static extern bool ACESocketClient_StartConnectServer( string strHostNamePort, DelegateProcessMessageBlock DelegateProcessMessageBlock, DelegateDisconnect DelegateDisconnect, ref IntPtr pSocketMainServer );

        /// <summary>
        /// 
        /// </summary>
        /// <param name="pSocketMainServer"></param>
        [DllImport("Demo G.O.S.E.Net.dll", CallingConvention = CallingConvention.StdCall)]
        private static extern void ACESocketClient_StopConnect( IntPtr pSocketMainServer );

        /// <summary>
        /// dll 调用
        /// </summary>
        /// <param name="pSocketMainServer"></param>
        /// <returns></returns>
        [DllImport("Demo G.O.S.E.Net.dll", CallingConvention = CallingConvention.StdCall)]
        private static extern bool ACESocketClient_IsConnected( IntPtr pSocketMainServer );

        /// <summary>
        /// dll 调用
        /// </summary>
        /// <param name="pBuffer"></param>
        /// <param name="iLength"></param>
        /// <param name="pSocketMainServer"></param>
        /// <returns></returns>
        [DllImport("Demo G.O.S.E.Net.dll", CallingConvention = CallingConvention.StdCall)]
        private static extern bool ACESocketClient_SendBuffer( IntPtr pBuffer, int iLength, IntPtr pSocketMainServer );

        /// <summary>
        /// dll 调用
        /// </summary>
        /// <param name="pSocketHandlerManagerAtClient"></param>
        /// <param name="pSocketMainServer"></param>
        /// <returns></returns>
        [DllImport("Demo G.O.S.E.Net.dll", CallingConvention = CallingConvention.StdCall)]
        private static extern bool ACESocketClient_GetSocketHandlerManager( ref IntPtr pSocketHandlerManagerAtClient, IntPtr pSocketMainServer );
        #endregion
    }
}
#endregion

